package com.iqismart.shorturl.service.impl;

import com.iqismart.shorturl.cache.UrlCountCache;
import com.iqismart.shorturl.config.UidHolder;
import com.iqismart.shorturl.config.WebSite;
import com.iqismart.shorturl.exception.BaseException;
import com.iqismart.shorturl.model.EntityUrl;
import com.iqismart.shorturl.repository.UrlRepository;
import com.iqismart.shorturl.service.LogService;
import com.iqismart.shorturl.service.UrlService;
import com.iqismart.shorturl.utils.IpUtils;
import com.iqismart.shorturl.utils.Ten2Sixty;
import com.iqismart.shorturl.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @Description
 * @Auther sty
 * @createTime 2019-10-14 11:26
 */
@Service
public class UrlServiceImpl implements UrlService {
    @Autowired
    protected UrlRepository urlRepository;

    @Autowired
    private LogService logService;

    private static boolean checkExpired = false;

    @Autowired
    private WebSite webSite;

    @Transactional
    @Override
    public EaddResponse eadd(EaddRequest request) {
        long uid = UidHolder.getUid();

        if(StringUtils.isEmpty(request.getLongurl()) || !request.getLongurl().contains(".") ){
            BaseException.failAndThrow("长链接格式不对");
        }

        Long id;
        EntityUrl entityUrl = null;
        //查询是否有过期一个月的
        List<EntityUrl> oldList = null;
        if(checkExpired){
            oldList = urlRepository.findAll((Specification<EntityUrl>) (root, cq, cb) -> {
                return cb.and(cb.greaterThan(root.get("expireAt"),0),cb.lessThan(root.get("expireAt"), System.currentTimeMillis() - 1000L * 3600 * 24 * 30));
            }, PageRequest.of(0, 1, Sort.Direction.DESC, "id")).getContent();
        }
        if(!CollectionUtils.isEmpty(oldList)){
            entityUrl = oldList.get(0);
            //清空旧I链接数据
            entityUrl.setExpireAt(0L);
            entityUrl.setCount(0L);
            entityUrl.setCountUnit("");
            entityUrl.setTimezone("");
            entityUrl.setTimezone("");
            entityUrl.setTarea("");
            entityUrl.setPassword("");
            entityUrl.setLongUrl("");
            entityUrl.setUpdateTime(System.currentTimeMillis());
            entityUrl.setUid(0L);
        }else{
            //新生成链接
            entityUrl = new EntityUrl();
        }

        //长链接
        if(!request.getLongurl().startsWith("http")){
            request.setLongurl("http://"+request.getLongurl());
        }
        entityUrl.setLongUrl(request.getLongurl());

        //有效时长
        if(StringUtils.isNotEmpty(request.getTimeCount())){
            String timeUnit = request.getTimeUnit();
            int min = 0;
            switch (timeUnit){
                case "分":
                    min = 1;
                    break;
                case "时":
                    min = 60;
                    break;
                case "天":
                    min = 60*24;
                    break;
                case "周":
                    min = 60*24*7;
                    break;
                case "月":
                    min = 60*24*30;
                    break;
                case "年":
                    min = 60*24*365;
                    break;
            }
            Long timeCount = Long.parseLong(request.getTimeCount());
            if(timeCount > 0){
                entityUrl.setExpireAt(System.currentTimeMillis() + 1000L*timeCount*min*60);
            }
        }else{
            entityUrl.setExpireAt(System.currentTimeMillis() + 1000L*3600*24*365);
        }

        //密码
        if(StringUtils.isNotEmpty(request.getPassword())){
            entityUrl.setPassword(request.getPassword());
        }

        //次 ip
        if(StringUtils.isNotEmpty(request.getCount()) && StringUtils.isNotEmpty(request.getCountUnit()) ){
            entityUrl.setCountUnit(request.getCountUnit());
            entityUrl.setCount(Long.parseLong(request.getCount()));

        }

        //可访问时段
        if(StringUtils.isNotEmpty(request.getTarea())){
            entityUrl.setTarea(request.getTarea());
        }

        //时区
        if(StringUtils.isNotEmpty(request.getTimezone())){
            entityUrl.setTimezone(request.getTimezone());
        }else{
            entityUrl.setTimezone("CTT");
        }

        entityUrl.setUid(uid);
        entityUrl = urlRepository.save(entityUrl);

        UrlCountCache.todayAdd.incrementAndGet();
        UrlCountCache.totalAdd.incrementAndGet();


        id = entityUrl.getId();

        ////将ID转换为36进制
        String shortString = Ten2Sixty.encode(id);

        EaddResponse response = new EaddResponse();
        response.setId(entityUrl.getId());

        response.setD(webSite.url +"/"+shortString);

        UrlCountCache.map.put("d",response.getD());

        return response;
    }

    @Override
    public UrlResponse getLongUrl(String shortUrl) {
        UrlResponse response = null;
        if(StringUtils.isEmpty(shortUrl)){
            return null;
        }
        //将shortUrl转换成10进制
        long id = Ten2Sixty.decode(shortUrl);

        EntityUrl entityUrl = null;
        try {
            entityUrl = urlRepository.findById(id).get();
            response =  entityUrl.toResponse();
        } catch (Exception e) {
            BaseException.failAndThrow("短链不存在");
        }

        //短链访问记录
        final LogRequest logRequest = new LogRequest();
        logRequest.setUrlId(id);

        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request =requestAttributes .getRequest();

        logRequest.setUserAgent(request.getHeader("User-Agent"));
        logRequest.setReferer(request.getHeader("Referer"));
        logRequest.setIp(IpUtils.getIpAddress(request));
        logService.add(logRequest);

        UrlCountCache.todayGet.incrementAndGet();
        UrlCountCache.totalGet.incrementAndGet();

        return response;
    }

    @Override
    public CheckUrlResponse checkurl(CheckUrlRequest request) {
        final EntityUrl entityUrl = urlRepository.findById(request.getId()).get();
        if(StringUtils.isEmpty(entityUrl.getPassword()) || entityUrl.getPassword().equals(request.getPassword())){
            final CheckUrlResponse response = new CheckUrlResponse();
            response.setLongUrl(entityUrl.getLongUrl());
            return response;
        }
        BaseException.failAndThrow("密码不正确");
        return null;
    }


}
